package com.springboot.demo.controller;

import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.springboot.demo.common.customValidator.ListNotHasNull;
import com.springboot.demo.entity.*;
import com.springboot.demo.entity.data.MsgData;
import com.springboot.demo.entity.validate.device.DevClusterDescGroup;
import com.springboot.demo.entity.validate.device.DevClusterNameGroup;
import com.springboot.demo.entity.validate.user.IdGroup;
import com.springboot.demo.entity.vo.DeviceClusterUser;
import com.springboot.demo.service.DeviceService;
import com.springboot.demo.utils.ResponseUtils;
import io.swagger.annotations.*;
import org.hibernate.validator.constraints.Length;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import javax.validation.constraints.*;
import java.util.List;

/**
 * @author wubc683
 * @desc
 * @date 2021-09-09 9:26
 */
@RestController
@Api(tags = "设备接口")
@Validated
public class DeviceController {
    @Autowired
    ResponseUtils responseUtils;
    @Autowired
    DeviceService deviceService;

    @GetMapping("/devCluster/all")
    @ApiOperation(value = "获取用户所有设备群信息")
    @ApiOperationSupport(order = 10)
    public ResponseUtils<PageResult<List<DeviceCluster>>> getAllDevClusterInfo(@Valid PageRequest pageRequest) {
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        UserDetailsImpl userDetailsImpl = (UserDetailsImpl) principal;
        Long ownerId = userDetailsImpl.getUser().getId();
        PageResult allDevClusterInfo = deviceService.getAllDevClusterInfo(pageRequest, ownerId);
        return responseUtils.buildSuccessResponse(allDevClusterInfo);
    }

    @GetMapping("/devCluster/{cid}")
    @ApiOperation(value = "获取设备群信息")
    @ApiOperationSupport(order = 20)
    public ResponseUtils<DeviceCluster> getDevClusterInfo(@PathVariable("cid") @ApiParam(value = "设备群id",
            required = true) Long cid) {
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        UserDetailsImpl userDetailsImpl = (UserDetailsImpl) principal;
        Long ownerId = userDetailsImpl.getUser().getId();
        DeviceCluster devClusterInfo = deviceService.getDevClusterInfo(ownerId, cid);
        return responseUtils.buildSuccessResponse(devClusterInfo);
    }

    @GetMapping("/devCluster/{cid}/users")
    @ApiOperation(value = "获取设备群用户信息")
    @ApiOperationSupport(order = 30)
    public ResponseUtils<PageResult<List<DeviceClusterUser>>> getDevClusterUserInfo(
            @PathVariable("cid") @ApiParam(value = "身边群id", required = true) Long cid,
            @Valid PageRequest pageRequest) {
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        UserDetailsImpl userDetailsImpl = (UserDetailsImpl) principal;
        Long ownerId = userDetailsImpl.getUser().getId();
        PageResult devClusterUserInfo = deviceService.getDevClusterUserInfo(pageRequest, ownerId, cid);
        return responseUtils.buildSuccessResponse(devClusterUserInfo);
    }

    @GetMapping("/devCluster/{cid}/devices")
    @ApiOperation(value = "获取设备群设备信息")
    @ApiOperationSupport(order = 40)
    public ResponseUtils<PageResult<List<Device>>> getDevClusterDevInfo(
            @PathVariable(value = "cid") @ApiParam(value = "设备群id", required = true) Long cid,
            @Valid PageRequest pageRequest,
            @RequestParam(value = "state", required = false) @ApiParam(value = "0:离线，1：在线") Integer state,
            //@RequestParam(value = "sceneName", required = false) @ApiParam("设备绑定的场景名") String sceneName,
            @ApiParam(value = "排序字段(最多1个）,字段名+空格+排序方向,示例：升序[id asc]，降序[id desc]")
            @RequestParam(value = "sort", required = false) String sort,
            @Length(max = 32, message = "搜索输入长度超过限制")
            @RequestParam(value = "search", required = false) @ApiParam(value = "搜索,不超过32位") String search) {
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        UserDetailsImpl userDetailsImpl = (UserDetailsImpl) principal;
        Long ownerId = userDetailsImpl.getUser().getId();
        PageResult devClusterDevInfo = deviceService.getDevClusterDevInfo(pageRequest, state, search, sort,
                ownerId, cid);
        return responseUtils.buildSuccessResponse(devClusterDevInfo);
    }

    @PostMapping("/devCluster")
    @ApiOperation(value = "创建设备群")
    @ApiOperationSupport(order = 50, includeParameters = {"deviceCluster.name", "deviceCluster.description"})
    public ResponseUtils createDevCluster(@Validated({DevClusterNameGroup.class, DevClusterDescGroup.class})
                                          @RequestBody DeviceCluster deviceCluster) {
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        UserDetailsImpl userDetailsImpl = (UserDetailsImpl) principal;
        Long ownerId = userDetailsImpl.getUser().getId();
        deviceService.createDevCluster(ownerId, deviceCluster);
        return responseUtils.buildSuccessResponse();
    }

    @PutMapping("/devCluster")
    @ApiOperation(value = "修改设备群信息")
    @ApiOperationSupport(order = 60, includeParameters = {"deviceCluster.id", "deviceCluster.name", "deviceCluster" +
            ".description"})
    public ResponseUtils updateDevCluster(@Validated({IdGroup.class, DevClusterNameGroup.class, DevClusterDescGroup.class})
                                          @RequestBody DeviceCluster deviceCluster) {
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        UserDetailsImpl userDetailsImpl = (UserDetailsImpl) principal;
        Long ownerId = userDetailsImpl.getUser().getId();
        deviceService.updateDevCluster(ownerId, deviceCluster);
        return responseUtils.buildSuccessResponse();
    }

    @DeleteMapping("/devCluster/{cid}")
    @ApiOperation(value = "删除设备群", notes = "设备群中没有设备才能删除")
    @ApiOperationSupport(order = 70)
    public ResponseUtils delDevCluster(@PathVariable("cid") @ApiParam(value = "设备群id", required = true) Long clusterId) {
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        UserDetailsImpl userDetailsImpl = (UserDetailsImpl) principal;
        Long ownerId = userDetailsImpl.getUser().getId();
        deviceService.delDevCluster(ownerId, clusterId);
        return responseUtils.buildSuccessResponse();
    }

//    @PutMapping("/devCluster/{cid}/user/{username}")
//    @ApiImplicitParams(value = {
//            @ApiImplicitParam(name = "cid", value = "设备群id"),
//            @ApiImplicitParam(name = "username", value = "用户名"),
//    })
//    @ApiOperationSupport(order = 80)
//    @ApiOperation(value = "移交设备群", notes = "设备群用户权限分3种:群主，管理员，用户，移交之后，群主变管理员，管理员变群主，群主只能一个，" +
//            "管理员多个")
//    public ResponseUtils transferDevCluster(@PathVariable("cid") Long clusterId,
//                                            @PathVariable("username") String username) {
//        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
//        UserDetailsImpl userDetailsImpl = (UserDetailsImpl) principal;
//        Long ownerId = userDetailsImpl.getUser().getId();
//        deviceService.transferDevCluster(ownerId, username.trim(), clusterId);
//        return responseUtils.buildSuccessResponse();
//    }
//
//    @PostMapping("/devCluster/{cid}/devices/devCluster/{name}")
//    @ApiOperation(value = "申请批量移交设备给别的设备群", notes = "移交者调用，要求是群主权限,移交设备操作有2步，" +
//            "一：移交者将设备群1的一些设备移交给设备群2,页面返回操作成功或者失败，后台会将此消息发送到被移交者收件箱" +
//            "二：设备群2的群主收到消息，会选择同意或者拒绝,并解析消息内容，发送答复请求给后台")
//    @ApiImplicitParams(value = {
//            @ApiImplicitParam(name = "cid", value = "移交设备群id", required = true),
//            @ApiImplicitParam(name = "name", value = "被移交设备群名字", required = true),
//            @ApiImplicitParam(name = "deviceIds", value = "设备id数组", required = true),
//    })
//    @ApiOperationSupport(order = 90)
//    public ResponseUtils transferDev2DevCluster(@PathVariable(value = "cid") Long clusterId,
//                                                @PathVariable(value = "name") String name,
//                                                @RequestBody @ListNotHasNull @Size(min = 1, message = "设备列表不能为空") List<Long> deviceIds) {
//        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
//        UserDetailsImpl userDetailsImpl = (UserDetailsImpl) principal;
//        User implUser = userDetailsImpl.getUser();
//        deviceService.applyTransferDev2DevCluster(implUser.getId(), implUser.getUsername(), clusterId, name.trim(), deviceIds);
//        return responseUtils.buildSuccessResponse();
//    }

//    @PutMapping("/devCluster/devices/devCluster")
//    @ApiOperation(value = "批准or拒绝批量移交设备给别的设备群")
//    @ApiOperationSupport(order = 100)
//    public ResponseUtils transferDev2DevCluster(@Valid @RequestBody MsgData msgData) {
//        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
//        UserDetailsImpl userDetailsImpl = (UserDetailsImpl) principal;
//        User implUser = userDetailsImpl.getUser();
//        deviceService.replyTransferDev2DevCluster(implUser.getId(), implUser.getUsername(), msgData);
//        return responseUtils.buildSuccessResponse();
//    }

//    @PostMapping("/device/claim/{did}")
//    @ApiOperation(value = "认领设备", notes = "将设备从设备群中认领，输入设备密码后，该设备就会进入[我的设备]列表，用户就可以使用设备了")
//    @ApiOperationSupport(order = 110)
//    public ResponseUtils claimDevCluster(@PathVariable("did") @ApiParam(value = "设备id", required = true) Long deviceId,
//                                         @Length(min = 8, max = 8, message = "密码格式错误")
//                                         @RequestParam("pwd") @ApiParam(value = "8位密码",
//                                                 required = true) String pwd) {
//        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
//        UserDetailsImpl userDetailsImpl = (UserDetailsImpl) principal;
//        User implUser = userDetailsImpl.getUser();
//        deviceService.claimDevCluster(implUser.getId(), deviceId, pwd);
//        return responseUtils.buildSuccessResponse();
//    }

    @PostMapping("/devices/auth/{auth}")
    @ApiOperation(value = "授权or取消授权一些设备给群内成员", notes = "要求群主或者管理员权限")
    @ApiOperationSupport(order = 120)
    public ResponseUtils authDev2Other(@RequestBody @ApiParam(value = "被授权用户id数组", required = true)
                                       @ListNotHasNull @Size(min = 1) List<Long> userIds,
                                       @PathVariable("auth") @ApiParam(value = "1表示授权，0表示取消授权", required = true) Integer auth,
                                       @RequestParam(value = "deviceId") @ApiParam(value = "设备id",required = true) Long deviceId) {
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        UserDetailsImpl userDetailsImpl = (UserDetailsImpl) principal;
        User implUser = userDetailsImpl.getUser();
        deviceService.authDev2Other(implUser.getId(), userIds, deviceId, auth);
        return responseUtils.buildSuccessResponse();
    }

    @PostMapping("/devCluster/devices")
    @ApiOperation(value = "批量删除群内设备", notes = "要求群主权限,给出提示：’需要通过plc软件重新注册设备或者从mico导入‘")
    @ApiOperationSupport(order = 130)
    public ResponseUtils delDevives(@RequestBody @ListNotHasNull @ApiParam(value = "设备id数组",required = true)
                                    @Size(min = 1) List<Long> deviceIds) {
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        UserDetailsImpl userDetailsImpl = (UserDetailsImpl) principal;
        User implUser = userDetailsImpl.getUser();
        deviceService.delDevices(implUser.getId(), deviceIds);
        return responseUtils.buildSuccessResponse();
    }

    @PutMapping("/devCluster/{cid}/user/{uid}/auth/{rid}")
    @ApiOperation(value = "变更设备群用户权限", notes = "要求群主权限,只能管理员变用户，或者用户变管理员")
    @ApiOperationSupport(order = 140)
    public ResponseUtils authDevClusterUser(@PathVariable("cid") @ApiParam(value = "设备群id", required = true) Long cid,
                                            @PathVariable("uid") @ApiParam(value = "用户id", required = true) Long uid,
                                            @PathVariable("rid") @ApiParam(value = "设备群角色id，1表示群主，2表示管理员，3表示用户",
                                                    required = true) Integer rid) {
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        UserDetailsImpl userDetailsImpl = (UserDetailsImpl) principal;
        User implUser = userDetailsImpl.getUser();
        deviceService.authDevClusterUser(implUser.getId(), cid, uid, rid);
        return responseUtils.buildSuccessResponse();
    }

    @PostMapping("/devCluster/{cid}/user/{name}")
    @ApiOperation(value = "邀请用户进入设备群")
    @ApiOperationSupport(order = 150)
    public ResponseUtils inviteDevClusterUser(@PathVariable("cid") @ApiParam(value = "设备群id", required = true) Long cid,
                                              @PathVariable("name") @ApiParam(value = "用户名,5~32位数字，英文大小写",
                                                      required = true) @NotBlank String name) {
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        UserDetailsImpl userDetailsImpl = (UserDetailsImpl) principal;
        User implUser = userDetailsImpl.getUser();
        deviceService.inviteDevClusterUser(implUser.getId(), cid, name);
        return responseUtils.buildSuccessResponse();
    }

    @PostMapping("/devCluster/invite/reply")
    @ApiOperation(value = "回复邀请用户进入设备群请求")
    @ApiOperationSupport(order = 151)
    public ResponseUtils replyInviteDevClusterUser(@Valid @RequestBody MsgData msgData) {
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        UserDetailsImpl userDetailsImpl = (UserDetailsImpl) principal;
        User implUser = userDetailsImpl.getUser();
        deviceService.replyInviteDevClusterUser(implUser.getId(), msgData);
        return responseUtils.buildSuccessResponse();
    }

    @DeleteMapping("/devCluster/{cid}/user/{uid}")
    @ApiOperation(value = "将用户踢出设备群", notes = "要求高一级权限,例如：群主可以踢管理员和用户，管理员只能踢出用户")
    @ApiOperationSupport(order = 160)
    public ResponseUtils delDevClusterUser(@PathVariable("cid") @ApiParam(value = "设备群id", required = true) Long cid,
                                           @PathVariable("uid") @ApiParam(value = "用户id", required = true) Long uid) {
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        UserDetailsImpl userDetailsImpl = (UserDetailsImpl) principal;
        User implUser = userDetailsImpl.getUser();
        deviceService.delDevClusterUser(implUser.getId(), cid, uid);
        return responseUtils.buildSuccessResponse();
    }

    @DeleteMapping("/devCluster/{cid}/quit")
    @ApiOperation(value = "退出设备群", notes = "群主不能退群，只能解散群，或者移交群")
    @ApiOperationSupport(order = 170)
    public ResponseUtils quitDevCluster(@PathVariable("cid") @ApiParam(value = "设备群id", required = true) Long cid) {
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        UserDetailsImpl userDetailsImpl = (UserDetailsImpl) principal;
        User implUser = userDetailsImpl.getUser();
        deviceService.quitDevCluster(implUser.getId(), cid);
        return responseUtils.buildSuccessResponse();
    }

    @PostMapping("/devCluster/{cid}/join")
    @ApiOperation(value = "申请加入设备群", notes = "已在群不能加入")
    @ApiOperationSupport(order = 170)
    public ResponseUtils applyJoinDevCluster(
            @PathVariable("cid") @ApiParam(value = "设备群id", required = true) Long cid) {
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        UserDetailsImpl userDetailsImpl = (UserDetailsImpl) principal;
        User implUser = userDetailsImpl.getUser();
        deviceService.applyJoinDevCluster(implUser.getId(), cid);
        return responseUtils.buildSuccessResponse();
    }

    @PostMapping("/devCluster/join/reply")
    @ApiOperation(value = "批准申请加入设备群")
    @ApiOperationSupport(order = 175)
    public ResponseUtils replyApplyJoinDevCluster(@Valid @RequestBody MsgData msgData) {
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        UserDetailsImpl userDetailsImpl = (UserDetailsImpl) principal;
        User implUser = userDetailsImpl.getUser();
        deviceService.replyApplyJoinDevCluster(implUser.getId(), msgData);
        return responseUtils.buildSuccessResponse();
    }


    @GetMapping("/devCluster/name")
    @ApiOperation(value = "查找设备群", notes = "支持模糊搜索")
    @ApiOperationSupport(order = 180)
    public ResponseUtils<List<DeviceCluster>> findDevCluster(
            @RequestParam("name") @ApiParam(value = "1~32位", required = true)
            @Size(min = 1, max = 32) String name,
            @Valid PageRequest pageRequest) {
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        UserDetailsImpl userDetailsImpl = (UserDetailsImpl) principal;
        User implUser = userDetailsImpl.getUser();
        PageResult devCluster = deviceService.findDevCluster(pageRequest, implUser.getId(), name.trim());
        return responseUtils.buildSuccessResponse(devCluster);
    }

    @GetMapping("/my/devices")
    @ApiOperation(value = "获取我的所有设备信息")
    @ApiOperationSupport(order = 190)
    public ResponseUtils<List<Device>> getMyDevicesInfo(@Valid PageRequest pageRequest) {
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        UserDetailsImpl userDetailsImpl = (UserDetailsImpl) principal;
        User implUser = userDetailsImpl.getUser();
        PageResult myDevicesInfo = deviceService.getMyDevicesInfo(pageRequest, implUser.getId());
        return responseUtils.buildSuccessResponse(myDevicesInfo);
    }

    @PostMapping("/my/devices")
    @ApiOperation(value = "批量删除我的设备")
    @ApiOperationSupport(order = 191)
    public ResponseUtils delMyDevices(@RequestBody @ListNotHasNull @Size(min = 1) List<Long> deviceIds) {
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        UserDetailsImpl userDetailsImpl = (UserDetailsImpl) principal;
        User implUser = userDetailsImpl.getUser();
        deviceService.delMyDevices(implUser.getId(), deviceIds);
        return responseUtils.buildSuccessResponse();
    }

    @GetMapping("/device/{id}")
    @ApiOperation(value = "获取设备信息")
    @ApiOperationSupport(order = 200)
    public ResponseUtils<Device> getDeviceInfo(@PathVariable("id") @ApiParam(value = "设备id", required = true) @Min(0) Long id) {
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        UserDetailsImpl userDetailsImpl = (UserDetailsImpl) principal;
        User implUser = userDetailsImpl.getUser();
        Device deviceInfo = deviceService.getDeviceInfo(implUser.getId(), id);
        return responseUtils.buildSuccessResponse(deviceInfo);
    }

    @PutMapping("/device")
    @ApiOperation(value = "修改设备信息")
    @ApiOperationSupport(order = 210, includeParameters = {"device.id", "device.description",
            "device.address", "device.province", "device.city", "device.region", "device.longitude", "device.latitude"})
    public ResponseUtils updateDeviceInfo(@Valid @RequestBody Device device) {
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        UserDetailsImpl userDetailsImpl = (UserDetailsImpl) principal;
        User implUser = userDetailsImpl.getUser();
        deviceService.updateDeviceInfo(implUser.getId(), device);
        return responseUtils.buildSuccessResponse();
    }

    @GetMapping("/mico/device")
    @ApiOperation(value = "从mico客户端获取设备信息")
    @ApiOperationSupport(order = 240)
    public ResponseUtils<PageResult<List<MicoDevice>>> getDevInfoFromMico(
            @RequestParam("username") @ApiParam(value = "用户名", required = true) String username,
            @RequestParam("password") @ApiParam(value = "密码", required = true) String password,
            @Valid PageRequest pageRequest,
            @ApiParam(value = "排序字段(最多1个）,字段名+空格+排序方向,示例：升序[id asc]，降序[id desc]")
            @RequestParam(value = "sort", required = false) String sort,
            @Length(max = 32, message = "搜索输入长度超过限制")
            @RequestParam(value = "search", required = false) @ApiParam(value = "搜索,不超过32位") String search) {
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        UserDetailsImpl userDetailsImpl = (UserDetailsImpl) principal;
        User implUser = userDetailsImpl.getUser();
        PageResult devInfoFromMico = deviceService.getDevInfoFromMico(implUser, username, password, pageRequest, sort, search);
        return responseUtils.buildSuccessResponse(devInfoFromMico);
    }

    @PostMapping("/mico/devices/cluster/{cid}")
    @ApiOperation(value = "导入设备", notes = "从mico客户端导入设备信息到网页服务器，默认全部勾选")
    @ApiOperationSupport(order = 250)
    public ResponseUtils addDevicesFromMico(@RequestParam("username") @ApiParam(value = "用户名", required = true) String username,
                                            @RequestParam("password") @ApiParam(value = "密码", required = true) String password,
                                            @PathVariable("cid") @ApiParam(value = "设备群id", required = true) Long cid,
                                            @RequestBody @ListNotHasNull @Size(min = 1) List<Long> deviceIds) {
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        UserDetailsImpl userDetailsImpl = (UserDetailsImpl) principal;
        User implUser = userDetailsImpl.getUser();
        deviceService.addDevicesFromMico(implUser, username, password, cid, deviceIds);
        return responseUtils.buildSuccessResponse();
    }

    @GetMapping("/device/{deviceId}/auth/{auth}/users")
    @ApiOperation("获取设备能授权或取消授权的用户")
    @ApiOperationSupport(order = 260)
    public ResponseUtils<PageResult<List<User>>> getDeviceAuthorityUsers(
            @PathVariable("deviceId") @ApiParam(value = "设备id", required = true) Long deviceId,
            @PathVariable("auth") @ApiParam(value = "授权标志，0取消授权，1授权", required = true) Integer auth,
            @Valid PageRequest pageRequest) {
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        UserDetailsImpl userDetailsImpl = (UserDetailsImpl) principal;
        User implUser = userDetailsImpl.getUser();
        PageResult deviceAuthorityUsers = deviceService.getDeviceAuthorityUsers(implUser, deviceId, auth, pageRequest);
        return responseUtils.buildSuccessResponse(deviceAuthorityUsers);
    }
}
